﻿namespace BorgExt
{
    public class Plug : MetaElement
    {
        internal bool reflectionHandlersAdded;

        internal MetaElementCollection<Slot> slotsWherePlugged;
        internal MetaElementCollection<Slot> slotsWhereSelected;

        internal CompositionEventHandler<CompositionEventArgs>[] PluggedEventHandlers { get; set; }
        internal CompositionEventHandler<CompositionEventArgs>[] UnpluggedEventHandlers { get; set; }

        internal CompositionEventHandler<CompositionEventArgs>[] SelectedEventHandlers { get; set; }
        internal CompositionEventHandler<CompositionEventArgs>[] DeselectedEventHandlers { get; set; }

        public Extension Extension { get; private set; }
        public PlugType PlugType { get; private set; }

        public bool AutoPlug { get; set; }
        public bool AutoSelect { get; set; }

        public MetaElementCollection<Param> Params { get; internal set; }

        public MetaElementCollection<Slot> SlotsWherePlugged
        {
            get { return InstanceStore.GetSlotsWherePlugged(this); }
        }

        public MetaElementCollection<Slot> SlotsWhereSelected
        {
            get { return InstanceStore.GetSlotsWhereSelected(this); }
        }

        public event CompositionEventHandler<CompositionEventArgs> Plugged
        {
            add
            {
                lock (LockObject)
                    PluggedEventHandlers = ArrayEx.Add(PluggedEventHandlers, value);
            }
            remove
            {
                lock (LockObject)
                    PluggedEventHandlers = ArrayEx.Remove(PluggedEventHandlers, value);
            }
        }

        public event CompositionEventHandler<CompositionEventArgs> Selected
        {
            add
            {
                lock (LockObject)
                    SelectedEventHandlers = ArrayEx.Add(SelectedEventHandlers, value);
            }
            remove
            {
                lock (LockObject)
                    SelectedEventHandlers = ArrayEx.Remove(SelectedEventHandlers, value);
            }
        }

        public event CompositionEventHandler<CompositionEventArgs> Unplugged
        {
            add
            {
                lock (LockObject)
                    UnpluggedEventHandlers = ArrayEx.Add(UnpluggedEventHandlers, value);
            }
            remove
            {
                lock (LockObject)
                    UnpluggedEventHandlers = ArrayEx.Remove(UnpluggedEventHandlers, value);
            }
        }

        public event CompositionEventHandler<CompositionEventArgs> Deselected
        {
            add
            {
                lock (LockObject)
                    DeselectedEventHandlers = ArrayEx.Add(DeselectedEventHandlers, value);
            }
            remove
            {
                lock (LockObject)
                    DeselectedEventHandlers = ArrayEx.Remove(DeselectedEventHandlers, value);
            }
        }

        internal Plug(int id, PlugType plugType, Extension extension)
            : base(id, plugType.Name)
        {
            slotsWherePlugged = new MetaElementCollection<Slot>();
            slotsWhereSelected = new MetaElementCollection<Slot>();
            
            PlugType = plugType;
            AutoPlug = plugType.AutoPlug;
            AutoSelect = plugType.AutoSelect;
            Extension = extension;
        }

        internal override AssemblyElement GetAssemblyElement()
        {
            return Extension.ExtensionType.Plugin;
        }
    }
}

